package showtime.framework.net
{
	import showtime.framework.events.SocketEvent;
	import showtime.framework.manager.supportClasses.cycle.CycleManager;
	import showtime.framework.manager.supportClasses.cycle.ICycleUnit;
	import showtime.framework.net.message.NetMessage;
	import showtime.framework.net.tcp.BaseSocket;
	
	import flash.utils.ByteArray;
	
	
	/** 
	 * @project DelphiFrmework
	 * @author yinhao.
	 * @date 2011-5-30
	 *
	 */
	
	public class HeartBeatChecker implements IHeartBeatChecker, ICycleUnit
	{

		private var lastTimestamp:Number = 0;
		
		private var _interval:int = 0;
		
		private var _keepAliveTimeout:int = 0;
		
		private var _socket:BaseSocket = null;
		/**
		 * Check is the socket connection is alive. 
		 */		
		public var isAlive:Boolean = false;
		
		/**
		 * Constructor.
		 *  
		 * @param timeout
		 * @param interval
		 * 
		 */		
		public function HeartBeatChecker(socket:BaseSocket, keepAliveTimeout:int, checkInterval:int)
		{
			_socket = socket;
			
			_interval = checkInterval;
			
			_keepAliveTimeout = keepAliveTimeout;
		
		}
		
		public function start():void
		{			
			CycleManager.getInstance().addUnit(this);
		}
		
		public function dispose():void
		{
			
		}
		
		public function initialize():void
		{
			
		}
		
		public function update():void
		{
			lastTimestamp = new Date().time;
		}
		
		/**
		 * This function to check the heart beat check logic.
		 * 
		 */		
		public function execute():void
		{			
			var message:ByteArray = new ByteArray();
			
			message.writeInt(NetMessage.HEADER_HEART_BEAT_CHECK);
			
			_socket.sendPacket(message);
		
			if (new Date().getTime() - lastTimestamp > _keepAliveTimeout)
			{
				_socket.dispatchEvent(new SocketEvent(SocketEvent.HEART_BEAT_ERROR));
				
				CycleManager.getInstance().removeUnit(this);
				
				_socket.close();	
			}
	
			
		}
		
		/**
		 * Trigger interivl ,time unit by millisecond. 
		 * @param delay
		 * 
		 */	
		public function getInterval():int
		{
			return _interval;
		}
		
		/**
		 * 
		 * @return 
		 * 
		 */		
		public function getUnitName():String
		{
			return String(HeartBeatChecker);
		}
	}
}